package io.github.bloquesoft.entity.storage.finding;

import io.github.bloquesoft.entity.definition.EntityDefinition;
import io.github.bloquesoft.entity.storage.PojoOperation;
import io.github.bloquesoft.entity.value.EntityValue;
import io.github.bloquesoft.entity.value.EntityValueFactory;
import io.github.bloquesoft.entity.value.ListPropertyValue;
import org.springframework.util.Assert;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class EntityFinding {

    public EntityValue findOne(EntityDefinition entityDefinition, Object id, PropertyTree propertyTree,PojoOperation pojoOperation,  EntityValueFactory entityValueFactory)
    {
        Object root = pojoOperation.findOne(entityDefinition, id);
        EntityValue rootEntityValue = entityValueFactory.create(entityDefinition, root, null);
        if (!rootEntityValue.isNullValue() && propertyTree != null)
        {
            loadProperty(rootEntityValue, propertyTree.getChildren(), pojoOperation, entityValueFactory);
        }
        return rootEntityValue;
    }

    private void loadProperty(EntityValue entityValue, List<PropertyTreeNode> propertyTreeNodes, PojoOperation pojoOperation, EntityValueFactory entityValueFactory)
    {
        for(PropertyTreeNode  propertyTreeNode : propertyTreeNodes)
        {
            ListPropertyValue listPropertyValue = entityValue.getListPropertyValue(propertyTreeNode.getPropertyName());
            Assert.notNull(listPropertyValue, "Could not find list property value named " + propertyTreeNode.getPropertyName());
            EntityDefinition listItemEntityDefinition = listPropertyValue.getListPropertyDefinition().getListItemEntityDefinition();
            String parentPropertyId = listItemEntityDefinition.getParentPojoProperty().getId();
            Object parentIdValue = entityValue.getPrimaryKeyValue().getValue();
            Map<String, Object> criteria = new HashMap<>();
            criteria.put(parentPropertyId, parentIdValue);
            List<Object> objectList = pojoOperation.findList(listPropertyValue.getListPropertyDefinition().getListItemEntityDefinition(), criteria);
            listPropertyValue.setValue(objectList);
            for(Object item : objectList)
            {
                EntityValue itemEntityValue = entityValueFactory.create(listItemEntityDefinition, item, entityValue);
                loadProperty(itemEntityValue, propertyTreeNode.getChildren(), pojoOperation, entityValueFactory);
            }
        }
    }
}
